package ar.com.tallerdos.smartdinner.activity;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import ar.com.tallerdos.smartdinner.R;
import ar.com.tallerdos.smartdinner.adapter.PedidoExpandableAdapter;
import ar.com.tallerdos.smartdinner.business.AgregadoBusiness;
import ar.com.tallerdos.smartdinner.business.ComidaBusiness;
import ar.com.tallerdos.smartdinner.business.MesaBusiness;
import ar.com.tallerdos.smartdinner.business.PedidoBusiness;
import ar.com.tallerdos.smartdinner.business.ProductoBusiness;
import ar.com.tallerdos.smartdinner.model.Agregado;
import ar.com.tallerdos.smartdinner.model.Comida;
import ar.com.tallerdos.smartdinner.model.Mesa;
import ar.com.tallerdos.smartdinner.model.Pedido;
import ar.com.tallerdos.smartdinner.model.Pedido.PedidoEstado;
import ar.com.tallerdos.smartdinner.model.Producto;
import ar.com.tallerdos.smartdinner.sync.CantidadComensalesNotificador;
import ar.com.tallerdos.smartdinner.sync.CerrarComida;
import ar.com.tallerdos.smartdinner.sync.GenericAsyncTask;
import ar.com.tallerdos.smartdinner.sync.NotificadorAbrirMesa;
import ar.com.tallerdos.smartdinner.sync.NotificadorPlatos;
import ar.com.tallerdos.smartdinner.sync.UpdateMesasSeleccionadas;
import ar.com.tallerdos.smartdinner.util.StringUtils;

public class ComidaActivity extends Activity {
    public final static String ID_PEDIDO_SELECCIONADO = "ar.com.tallerdos.smartdinner.activity.ComidaActivity.ID_PEDIDO_SELECCIONADO";

    private PedidoExpandableAdapter listAdapter;
    private ExpandableListView expListView;
    private Comida comida;
    private int retorno;
    
    private static Pedido pedidoSeleccion;

    private int selectedPosition;
    private static ComidaActivity context;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	
	context = this;
	
	setContentView(R.layout.comida_activity);

	Intent intent = getIntent();
	if (intent.getIntExtra(ComidasLista.ACCION_KEY, 0) == ComidasLista.ACCION_ABRIR_MESA) {
	    this.comida = new Comida();
	    Intent intentSelecMesas = new Intent(this, SeleccionarMesasActivity.class);
	    startActivityForResult(intentSelecMesas, 2);

	} else if (intent.getIntExtra(ComidasLista.ACCION_KEY, 0) == ComidasLista.ACCION_VER_MESA) {
	    
	    int idComida = intent.getIntExtra(ComidasLista.COMIDA_SELECCIONADA, 0);
	    comida = ComidaBusiness.findById(idComida);
	    initLayout();
	} else {
	    throw new NullPointerException(); // TODO manejar esto
					      // apropiadamente
	}
	
	setUpBotones();

	final ComidaActivity context = this;
	Thread timer = new Thread(){
		public void run(){
			for(;;){
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				NotificadorPlatos dlTask = new NotificadorPlatos(context);
				dlTask.execute();
			}
		}
	};
	timer.start();
	
    }
    
    private void setUpBotones() {
	Button cerrarBtn = (Button) findViewById(R.id.cerrarMesaBtn);
	Button facturarBtn = (Button) findViewById(R.id.facturarMesa);
	if (this.comida.getCerrado()) {
	    cerrarBtn.setVisibility(View.INVISIBLE);
	    facturarBtn.setVisibility(View.VISIBLE);
	    Button agregarPedidoBtn = (Button) findViewById(R.id.agregarPedidoBtn);
	    agregarPedidoBtn.setVisibility(View.INVISIBLE);
	} else {
	    cerrarBtn.setVisibility(View.VISIBLE);
	    facturarBtn.setVisibility(View.INVISIBLE);	    
	}
    }

    private void actualizarMesasSeleccionadasLabel() {
	TextView header = (TextView) findViewById(R.id.mesaNroLabel);
	header.setText(comida.toString());	
    }

    private void initLayout() {
	expListView = (ExpandableListView) findViewById(R.id.pedidosListado);
	expListView.setEmptyView(findViewById(android.R.id.empty));
	if (comida.getPedidos() == null) {
	    comida.setPedidos(new ArrayList<Pedido>());
	}

	listAdapter = new PedidoExpandableAdapter(this, comida.getPedidos());
	expListView.setAdapter(listAdapter);
	
	registerClickCallBack();
	
	actualizarDescripcionMesasSeleccionadas();
	recalcularTotal();
	actualizarMesasSeleccionadasLabel();
	EditText cantComensales = (EditText) findViewById(R.id.cantComensalesValue);
	cantComensales.setText(comida.getCantidadComensales().toString());
	cantComensales.setOnEditorActionListener(new OnEditorActionListener() {
	    
	    @Override
	    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
		ComidaActivity activity = ComidaActivity.this;
		if (!"".equals(v.getText().toString()) && 
			!Integer.valueOf(v.getText().toString()).equals(activity.comida.getCantidadComensales())) {
		    activity.comida.setCantidadComensales(Integer.valueOf(v.getText().toString()));
		    new GenericAsyncTask(new CantidadComensalesNotificador(activity.comida)).execute();
		} else {
		    v.setText(activity.comida.getCantidadComensales().toString());
		}	
		
		return false;
	    }
	});
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
	getMenuInflater().inflate(R.menu.main_menu, menu);
	return true;
    }

    public void agregarPedido(View view) {
	Intent intent = new Intent(this, RubrosLista.class);
	startActivityForResult(intent, 1);
    }

    public void cerrarMesa(View view) {
	if (!sePuedeCerrar()) {
	    Toast.makeText(getApplicationContext(), getResources().getString(R.string.cerrarMesaError), Toast.LENGTH_SHORT).show();
	} else {
	    this.comida.setCerrado(true);
	    setUpBotones();
	    new GenericAsyncTask(new CerrarComida(comida)).execute();
	}
    }
    
    private boolean sePuedeCerrar() {
	for (Pedido p : this.comida.getPedidos()) {
	    if (!(p.getEstado().equals(PedidoEstado.Cancelado) || 
		  p.getEstado().equals(PedidoEstado.Entregado))) {
		return false;
	    }
	}
	return true;
    }

    public void facturarMesa(View view) {
	if (!this.comida.getFacturado()) {
	    Toast.makeText(getApplicationContext(),
		    getResources().getString(R.string.entregarFacturaError),
		    Toast.LENGTH_SHORT).show();
	} else {
	    this.comida.setFacturaEntregada(true);
	    new GenericAsyncTask(new CerrarComida(comida)).execute();
	    setResult(RESULT_OK, new Intent());
	    finish();
	}
    }

    public void recalcularTotal() {
	TextView totalTextView = (TextView) findViewById(R.id.totalValor);
	totalTextView.setText("$ " + this.comida.getTotalDosDecimales());
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    int positionGrupo;	
    retorno = resultCode;
    
	if (requestCode == 1) {
	    if (resultCode == RESULT_OK) {
		int productoId = data.getIntExtra("result", 0);
		if (productoId != 0) {
		    Pedido pedido = new Pedido();
		    Producto producto = ProductoBusiness.findById(productoId);
		    pedido.setProducto(producto);
		    pedido.setComida(this.comida);
		    PedidoBusiness.create(pedido);
		    this.comida.getPedidos().add(pedido);
		    recalcularTotal();

		    positionGrupo = listAdapter.getGroupCount();

		    expListView.expandGroup(positionGrupo - 1);
		    expListView.setSelection(positionGrupo - 1);
		    expListView.smoothScrollToPosition(positionGrupo);
		    
		    listAdapter.notifyDataSetChanged();
		}
	    }
	    if (resultCode == RESULT_CANCELED) {
	    }
	} else if (requestCode == 2) {
	    if (this.comida.getId() == null) {
		darDeAltaNuevaComida(resultCode, data);	
	    } else {
		actualizarMesas(resultCode, data);
	    }
	} else if (requestCode == 3) {
	    if (resultCode == RESULT_OK) {
		String agregadosIds = data.getStringExtra("result");
		pedidoSeleccion.getAgregados().clear();
		if (agregadosIds != null && !agregadosIds.isEmpty()) {	
		    for (String idStr : agregadosIds.split(",")) {
			Agregado agregado = AgregadoBusiness.findById(Integer.valueOf(idStr));
			pedidoSeleccion.getAgregados().add(agregado);
		    }
		    PedidoBusiness.update(pedidoSeleccion);
		    listAdapter.notifyDataSetChanged();
		}
	    }
	    if (resultCode == RESULT_CANCELED) {
	    }
	}
    }
    
    private void actualizarMesas(int resultCode, Intent data) {
    	
    retorno = resultCode;	
	if (resultCode == RESULT_OK) {
	    String mesasIds = data.getStringExtra("result");
	    List<Mesa> nuevaSeleccion = parsearMesasIds(mesasIds);
	    if (!Mesa.sonIguales(this.comida.getMesas(), nuevaSeleccion)) {
		this.comida.setMesas(nuevaSeleccion);
		new GenericAsyncTask(new UpdateMesasSeleccionadas(this.comida.getCodigo(), nuevaSeleccion), this).execute();
		actualizarMesasSeleccionadasLabel();
	    }
	}
	
    }

    private void darDeAltaNuevaComida(int resultCode, Intent data) {
    retorno = resultCode;
	if (resultCode == RESULT_OK) {
	    String mesasIds = data.getStringExtra("result");
	    this.comida.setMesas(parsearMesasIds(mesasIds));
	    ComidaBusiness.create(this.comida);
	    new GenericAsyncTask(new NotificadorAbrirMesa(this.comida), this).execute();
	    initLayout();
	}
	if (resultCode == RESULT_CANCELED) {
	    onBackPressed();
	}
    }
    
    private List<Mesa> parsearMesasIds(String mesasId) {
	List<Mesa> mesas = new ArrayList<Mesa>();
	if (!mesasId.isEmpty()) {
	    for (String id : mesasId.split(",")) {
		Mesa mesa = MesaBusiness.findById(Integer.valueOf(id));
		mesas.add(mesa);
	    }
	}
	return mesas;
    }
    
    public void confirmarAltaComida(Integer id) {
	if (id != 0) {
	    this.comida.setCodigo(id);	    
	} else {
	    //TODO manejar este error.
	}
    }

    private void actualizarDescripcionMesasSeleccionadas() {
	TextView descripcion = (TextView) findViewById(R.id.mesaNroLabel);
	descripcion.setText(this.comida.toString());
    }

    @Override
    public void onBackPressed() {
	//super.onBackPressed();
    	TextView comensales = (TextView) findViewById(R.id.cantComensalesValue);
    	
    	if(retorno == RESULT_OK ){    		
			if (this.comida.getCantidadComensales() != Integer
					.parseInt(comensales.getText().toString())) {
				this.comida.setCantidadComensales(Integer.parseInt(comensales
						.getText().toString()));
				ComidaBusiness.update(this.comida);
				new GenericAsyncTask(new CantidadComensalesNotificador(
						this.comida)).execute();
			}
			Intent returnIntent = new Intent();
			setResult(RESULT_OK, returnIntent);
			finish();
    	} else {
    		Intent returnIntent = new Intent();
    		setResult(RESULT_CANCELED, returnIntent);
    		finish();
    	}
    }
    
    public static void setPedidoSeleccion(Pedido pedido){
    	pedidoSeleccion = pedido;
    }
    
    public void cambiarMesas(View view) {
	Intent intentSelecMesas = new Intent(this, SeleccionarMesasActivity.class);
	intentSelecMesas.putExtra(SeleccionMultipleActivity.PRE_SELECCION, StringUtils.concatenarIds(this.comida.getMesas(), SeleccionMultipleActivity.SEPARADOR_IDS));
	startActivityForResult(intentSelecMesas, 2);	
    }
    
    public ExpandableListView getListView(){
    	return this.expListView;
    }
    
    public PedidoExpandableAdapter getListAdapter(){
    	return listAdapter;
    }
    
    public Comida getComida(){
    	return this.comida;
    }
    
    public static ComidaActivity getContext(){
    	return context;
    }
    
    private void registerClickCallBack() {
    	
    	expListView.setOnItemLongClickListener(new OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,int arg2, long arg3) {
				
				selectedPosition = arg2;
				showPopup(ComidaActivity.getContext());
				return false;
			}
		});	
	}
    
 // The method that displays the popup.
    private void showPopup(final Activity context) {
    	
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        
        int popupWidth = size.x;
        int popupHeight = 200;
     
       // Inflate the popup_layout.xml
       RelativeLayout viewGroup = (RelativeLayout) context.findViewById(R.id.popup);
       LayoutInflater layoutInflater = (LayoutInflater) context
         .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       final View layout = layoutInflater.inflate(R.layout.comentario_pop_up, viewGroup);
     
       // Creating the PopupWindow
       final PopupWindow popup = new PopupWindow(context);
       popup.setContentView(layout);
       popup.setWidth(popupWidth);
       popup.setHeight(popupHeight);
       popup.setFocusable(true);
     
       // Some offset to align the popup a bit to the right, and a bit down, relative to button's position.
       int OFFSET_X = 0;
       int OFFSET_Y = 100;
       
       // Displaying the popup at the specified location, + offsets.
       popup.showAtLocation(layout, Gravity.NO_GRAVITY, OFFSET_X, OFFSET_Y);
     
       // Getting a reference to Close button, and close the popup when clicked.
       Button close = (Button) layout.findViewById(R.id.cancelarpopup);
       close.setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {
           popup.dismiss();
         }
       });
       
       Button guardar = (Button) layout.findViewById(R.id.aceptarpopup);
       guardar.setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {
           Pedido pedido = (Pedido) expListView.getItemAtPosition(selectedPosition);
        
           if(pedido != null){
        	   TextView comentario = (TextView) layout.findViewById(R.id.comentario);
        	   pedido.setComentario(comentario.getText().toString());
        	   PedidoBusiness.update(pedido);
           }
           popup.dismiss();
         }
       });
    }
}
